﻿#include "FSpinBox.h"
#include "../Base/FTheme.h"

#include <QPainter>
#include <QMouseEvent>


FSpinBox::FSpinBox(QWidget *parent)
    : QSpinBox{parent}
{
    QString qss = QString(R"(
FSpinBox {
    border: 1px solid %1;
    border-radius: 2px;
    padding: 2px 2px;
    background: %5;
}
FSpinBox:hover {
    border: 1px solid %2;
}
FSpinBox:focus {
    border: 1px solid %3;
}
FSpinBox:disabled {
    background: 1px solid %4;
}
FSpinBox::up-arrow, FSpinBox::down-arrow {
    width: 0; height: 0;
}
FSpinBox::up-button, FSpinBox::down-button {
    background: transparent;
    border: none;
}
)").arg(FColors::getBaseColor(FColors::Default).name(QColor::HexArgb),
       FColors::getHoverColor(FColors::Default).name(QColor::HexArgb),
       FColors::getActiveColor(FColors::Default).name(QColor::HexArgb),
       FColors::getDisabledColor(FColors::Default).name(QColor::HexArgb),
       FColors::getBackgroundColor().name(QColor::HexArgb));

    setStyleSheet(qss);
    setContextMenuPolicy(Qt::CustomContextMenu);
}

QRect FSpinBox::upRect() const
{
    int w = 20;
    return QRect(width()-w, 1, w, height()/2);
}

QRect FSpinBox::dnRect() const
{
    int w = 20;
    return QRect(width()-w, 1+height()/2, w, height()/2);
}

void FSpinBox::resetHover()
{
    m_hoverUp = m_hoverDown = false;
    update();
}

void FSpinBox::updateHoverState(const QPoint &pos)
{
    QRect upR = upRect();
    QRect dnR = dnRect();

    bool upNew = upR.contains(pos);
    bool dnNew = dnR.contains(pos);

    if (upNew != m_hoverUp || dnNew != m_hoverDown)
    {
        m_hoverUp = upNew;
        m_hoverDown = dnNew;
        update();
    }
}

void FSpinBox::updatePressState(const QPoint &pos, bool pressed)
{
    QRect upR = upRect();
    QRect dnR = dnRect();

    m_pressUp = pressed && upR.contains(pos);
    m_pressDown = pressed && dnR.contains(pos);
    update();
}

void FSpinBox::paintEvent(QPaintEvent *event)
{
    QSpinBox::paintEvent(event);

    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing, true);

    int s = height() * 0.24;   // 箭头大小

    auto drawArrow = [&](const QRect &rect, bool up)
    {
        QPoint center = rect.center();
        qreal half = s * 0.65;   // 左右展开
        qreal h    = s * 0.8;    // 高度

        QPointF top(center.x(), center.y() + (up ? -h*0.2 : h*0.2));
        QPointF left(center.x() - half, center.y() + (up ? h*0.4 : -h*0.4));
        QPointF right(center.x() + half, center.y() + (up ? h*0.4 : -h*0.4));

        QColor color = FColors::getBaseColor(FColors::Default);

        // 状态切色
        if ((up && m_pressUp) || (!up && m_pressDown))
            color = FColors::getActiveColor(FColors::Default);        // 按压色（蓝）
        else if ((up && m_hoverUp) || (!up && m_hoverDown))
            color = FColors::getHoverColor(FColors::Default);           // hover色
        else
            color = FColors::getBaseColor(FColors::Info);          // 默认色

        QPen pen(color, 2);
        p.setPen(pen);

        p.drawLine(top, left);
        p.drawLine(top, right);
    };

    drawArrow(upRect(), true);   // ↑
    drawArrow(dnRect(), false);  // ↓
}

void FSpinBox::enterEvent(QEvent *e)
{
    updateHoverState(mapFromGlobal(QCursor::pos()));
    QSpinBox::enterEvent(e);
}

void FSpinBox::leaveEvent(QEvent *e)
{
    resetHover();
    QSpinBox::leaveEvent(e);
}

void FSpinBox::mousePressEvent(QMouseEvent *e)
{
    updatePressState(e->pos(), true); QSpinBox::mousePressEvent(e);
    QSpinBox::mousePressEvent(e);
}

void FSpinBox::mouseReleaseEvent(QMouseEvent *e)
{
    updatePressState(e->pos(), false); QSpinBox::mouseReleaseEvent(e);
    QSpinBox::mouseReleaseEvent(e);
}
